/*
  The <out_buffer.c> implements buffering functions for outputting data
 */

#include <stdlib.h>
#include <syscall.h>
#include <stdio.h>
#include <out_buffer.h>


/* Data structures */
byte_t ob_data[OB_SIZE];
int ob_head,ob_tail,ob_free_space;

/* private functions prototypes */

inline int ob_empty(void);
inline int ob_full(void);
inline void ob_increment(int *idx);
inline int ob_length(void);

/* public buffering functions */

void ob_clear(void)
  {
    ob_head=0;
    ob_tail=0;
    ob_free_space=OB_SIZE;
  }

void ob_submit(void)
  {
    // send buffer to kernel
    if (!ob_empty())
      write(stdout,ob_data,ob_length());
  }

int ob_enqueue(int n)
  {
    // send this for now...
    if (ob_full())
      {
	ob_submit();
	ob_clear();
      }

    ob_data[ob_tail]=n;
    ob_increment(&ob_tail);
    ob_free_space--;

    return 0;
  }

/* private buffering functions */

inline int ob_empty(void)
  {
    return ob_free_space==OB_SIZE;
  }

inline int ob_full(void)
  {
    return ob_free_space==0;
  }

inline void ob_increment(int *idx)
  {
    // it's like (*idx+1)&OB_SIZE but faster.
    *idx=(*idx+1)&(OB_SIZE-1);    
  }

inline int ob_length(void)
  {
    return ob_tail-ob_head;
  }
